package com.sparrow.common.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 分页工具类，提供分页相关的计算方法。
 */
public class PageUtil {

    /**
     * 该方法用于根据记录总数和每页显示的记录数来计算最大页数。
     *
     * @param totalRecords 记录的总数，应当为非负数。
     * @param pageSize 每页显示的记录数，应当为正整数。
     * @return 返回计算得到的最大页数，结果为正整数。
     * @throws IllegalArgumentException 当 totalRecords 为负数或者 pageSize 小于等于 0 时抛出此异常。
     */
    public static int getMaxPage(int totalRecords, int pageSize) {
        // 检查参数的有效性
        if (totalRecords < 0) {
            throw new IllegalArgumentException("记录总数不能为负数: " + totalRecords);
        }
        if (pageSize <= 0) {
            throw new IllegalArgumentException("每页记录数必须为正整数: " + pageSize);
        }

        // 计算最大页数
        return (totalRecords + pageSize - 1) / pageSize;
    }

    /**
     * 计算指定页码的偏移量。
     *
     * @param pageNumber 当前页码，应当为正整数。
     * @param pageSize 每页显示的记录数，应当为正整数。
     * @return 计算得到的偏移量，为非负整数。
     * @throws IllegalArgumentException 当 pageNumber 小于等于 0 或者 pageSize 小于等于 0 时抛出此异常。
     */
    public static int getOffset(int pageNumber, int pageSize) {
        if (pageNumber <= 0) {
            throw new IllegalArgumentException("页码必须为正整数: " + pageNumber);
        }
        if (pageSize <= 0) {
            throw new IllegalArgumentException("每页记录数必须为正整数: " + pageSize);
        }
        return (pageNumber - 1) * pageSize;
    }

    /**
     * 判断给定的页码是否有效。
     *
     * @param pageNumber 要检查的页码。
     * @param totalRecords 记录的总数，应当为非负数。
     * @param pageSize 每页显示的记录数，应当为正整数。
     * @return 如果页码有效返回 true，否则返回 false。
     */
    public static boolean isValidPageNumber(int pageNumber, int totalRecords, int pageSize) {
        if (pageNumber <= 0) {
            return false;
        }
        int maxPage = getMaxPage(totalRecords, pageSize);
        return pageNumber <= maxPage;
    }

    /**
     * 确保页码在有效范围内。
     * 如果页码小于 1，则返回 1；如果页码大于最大页数，则返回最大页数。
     *
     * @param pageNumber 要检查的页码。
     * @param totalRecords 记录的总数，应当为非负数。
     * @param pageSize 每页显示的记录数，应当为正整数。
     * @return 调整后在有效范围内的页码。
     */
    public static int ensureValidPageNumber(int pageNumber, int totalRecords, int pageSize) {
        int maxPage = getMaxPage(totalRecords, pageSize);
        if (pageNumber < 1) {
            return 1;
        }
        return Math.min(pageNumber, maxPage);
    }

    /**
     * 从列表中获取指定分页的内容。
     *
     * @param list 原始列表
     * @param pageNumber 页码，从 1 开始
     * @param pageSize 每页显示的记录数
     * @param <T> 列表元素的类型
     * @return 指定分页的内容列表
     */
    public static <T> List<T> getPageContent(List<T> list, int pageNumber, int pageSize) {
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        int totalRecords = list.size();
        int offset = getOffset(pageNumber, pageSize);
        int endIndex = Math.min(offset + pageSize, totalRecords);
        if (offset >= totalRecords) {
            return Collections.emptyList();
        }
        return new ArrayList<>(list.subList(offset, endIndex));
    }

}